package com.yoooya.base.config;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.sql.DataSource;
import java.beans.PropertyVetoException;

@Configuration
@EnableTransactionManagement
public class DalConfig implements EnvironmentAware {

    private Environment environment;

    @Bean(destroyMethod = "close")
    public DataSource dataSource() {
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        try {
            dataSource.setDriverClass(environment.getProperty("db.driver", "com.mysql.jdbc.Driver"));
        } catch (PropertyVetoException e) {
            throw new RuntimeException(e.getMessage(), e);
        }
        dataSource.setUser(environment.getRequiredProperty("db.username"));
        dataSource.setPassword(environment.getRequiredProperty("db.password"));
        dataSource.setJdbcUrl(environment.getRequiredProperty("db.jdbc.url"));
        dataSource.setInitialPoolSize(environment.getProperty("dal.init.pool.size", int.class, 10));
        dataSource.setMinPoolSize(environment.getProperty("dal.min.pool.size", int.class, 5));
        dataSource.setMaxPoolSize(environment.getProperty("dal.max.pool.size", int.class, 30));
        dataSource.setMaxIdleTime(environment.getProperty("dal.max.idle.time", int.class, 60));
        dataSource.setAcquireIncrement(environment.getProperty("dal.acquire.increment", int.class, 5));
        dataSource.setIdleConnectionTestPeriod(environment.getProperty("dal.idle.conn.test.period", int.class, 60));
        dataSource.setAcquireRetryAttempts(environment.getProperty("dal.acquire.retry.attempts", int.class, 20));
        dataSource.setBreakAfterAcquireFailure(environment.getProperty("dal.break.after.acquire.failure", boolean.class, true));
        dataSource.setMaxStatements(environment.getProperty("dal.max.statements", int.class, 0));
        dataSource.setTestConnectionOnCheckout(environment.getProperty("dal.test.conn.checkout", boolean.class, false));
        return dataSource;
    }

    @Bean
    public PlatformTransactionManager transactionManager() {
        return new DataSourceTransactionManager(dataSource());
    }

    @Bean
    public PersistenceExceptionTranslationPostProcessor persistenceExceptionTranslationPostProcessor() {
        return new PersistenceExceptionTranslationPostProcessor();
    }

    @Override
    public void setEnvironment(Environment environment) {
        this.environment = environment;
    }

}
